﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Dapper;
using DapperExtensions;
using MaximServices.Common;
using MaximServices.Data;
using MaximServices.Model;
using Microsoft.Extensions.Options;
using MySql.Data.MySqlClient;

namespace MaximServices.Repository
{
    public class MottoRuleRepository
    {
        private readonly DataBaseRepository _dbrsp;

        public MottoRuleRepository(DataBaseRepository dbrsp)
        {
            _dbrsp = dbrsp;
        }

        public void Dispose()
        {
            _dbrsp.Database.Dispose();
        }
        /// <summary>
        /// 根据规则名称获取列表
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public List<MottoRule> GetModelByName(string name)
        {
            var p = Predicates.Field<MottoRule>(c => c.Rule_Name, Operator.Eq, name);
            var list = _dbrsp.Database.GetList<MottoRule>(p, null, null, false).ToList();
            return list;
        }

        public MottoRule GetModelById(string Id)
        {
            var p = Predicates.Field<MottoRule>(c => c.Id, Operator.Eq, Id);
            var model = _dbrsp.Database.GetList<MottoRule>(p, null, null, false).FirstOrDefault();
            return model;
        }

        public List<MottoRule> GetList(List<string> ids)
        {
            string sql = $"select * from motto_rule where id in ({string.Join(',', ids)})";
            List<MottoRule> result = _dbrsp.Database.Connection.Query<MottoRule>(sql).ToList();
            return result;
        }

        public MottoRule GetSingleByDate(DateTime date)
        {
            string sql = $"select * from motto_rule where id = (select rule_id from date_detail where target_date='{date.ToString("yyyy-MM-dd")}' limit 1)";
            MottoRule result = _dbrsp.Database.Connection.Query<MottoRule>(sql).FirstOrDefault();
            return result;
        }

        /// <summary>
        /// 查询规则列表
        /// </summary>
        /// <param name="model"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public PageData<MottoRule> GetList(MottoRule model,int pageIndex, int pageSize)
        {
            var pg = new PredicateGroup { Operator = GroupOperator.And, Predicates = new List<IPredicate>() };
            if (null != model.StartDate)
                pg.Predicates.Add(Predicates.Field<MottoRule>(c => c.StartDate, Operator.Ge, model.StartDate));
            if(null != model.EndDate)
                pg.Predicates.Add(Predicates.Field<MottoRule>(c => c.EndDate, Operator.Le, model.EndDate));

            if(!string.IsNullOrWhiteSpace(model.Rule_Name))
                pg.Predicates.Add(Predicates.Field<MottoRule>(c => c.Rule_Name, Operator.Like, model.Rule_Name));

            IList<ISort> sort = new List<ISort>();
            
            sort.Add(new Sort { PropertyName = "Create_Time", Ascending = false });
            sort.Add(new Sort { PropertyName = "Sort_Order", Ascending = true });
            int count = _dbrsp.Database.Count<MottoRule>(pg,null);
            var list = _dbrsp.Database.GetPage<MottoRule>(pg, sort,pageIndex-1 ,pageSize,null,false).ToList();
            PageData<MottoRule> result = new PageData<MottoRule>
            {
                pageIndex = pageIndex,
                pageSize = pageSize,
                Total = count,
                DataList = list
            };
            return result;
        }

        public bool CreateMottoRule(MottoRule model,List<DateDetail> dateDetails)
        {
            try
            {
                _dbrsp.Database.BeginTransaction();
                _dbrsp.Database.Insert(model, null);
                dateDetails.ForEach(d =>
                {
                    _dbrsp.Database.Insert(d, null);
                });
                _dbrsp.Database.Commit();
                return true;
            }
            catch (Exception)
            {
                _dbrsp.Database.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 修改规则
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool ModifyMottoRule(MottoRule model)
        {
            try
            {
                var query = _dbrsp.Database.Get<MottoRule>(model.Id, null);
                if (null == query)
                    throw new Exception("Id不存在");
                
                var p = Predicates.Field<DateDetail>(f => f.Rule_Id, Operator.Eq, model.Id);
                var details = _dbrsp.Database.GetList<DateDetail>(p, null,null,null,false).ToList();

                _dbrsp.Database.BeginTransaction();
                

                //修改详细日期
                if (query.StartDate != model.StartDate || query.EndDate != model.EndDate)
                {
                    List<DateDetail> dateDetails = new List<DateDetail>();
                    for (DateTime i = model.StartDate.Value; i <= model.EndDate.Value; i = i.AddDays(1))
                    {
                        dateDetails.Add(new DateDetail
                        {
                            Id = IdFactory.NextId,
                            Target_Date = i,
                            Rule_Id = model.Id
                        });
                    }
                    
                    
                    details.ForEach(d =>
                    {
                        _dbrsp.Database.Delete(d,null);
                    });
                    dateDetails.ForEach(d =>
                    {
                        _dbrsp.Database.Insert(d, null);
                    });
                }
                query.Rule_Name = model.Rule_Name;
                query.Rule_Json = model.Rule_Json;
                query.Modify_Time = model.Modify_Time;
                query.StartDate = model.StartDate;
                query.EndDate = model.EndDate;
                query.Usedefault_Rule = model.Usedefault_Rule;
                _dbrsp.Database.Update(query,null);
                //提交事务
                _dbrsp.Database.Commit();
                return true;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {
                if(_dbrsp.Database.HasActiveTransaction)
                    _dbrsp.Database.Rollback();
            }
        }
        /// <summary>
        /// 删除规则
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public bool DeleteMottoRule(long Id)
        {
            try
            {
                var query = _dbrsp.Database.Get<MottoRule>(Id, null);
                if (null == query)
                    throw new Exception("Id不存在");

                var p = Predicates.Field<DateDetail>(f => f.Rule_Id, Operator.Eq, Id);
                var details = _dbrsp.Database.GetList<DateDetail>(p, null, null, null, false).ToList();

                _dbrsp.Database.BeginTransaction();
                //先删除规则
                _dbrsp.Database.Delete(query,null);
                //再删除对应的日期详情
                details.ForEach(d => _dbrsp.Database.Delete(d, null));

                _dbrsp.Database.Commit();
                return true;
            }
            catch (Exception)
            {
                _dbrsp.Database.Rollback();
                throw;
            }
        }
    }
}
